#!/usr/bin/env python
#-*- coding:utf-8 -*-


import gtk
from array import *

from Progresso import *





METODO_COMBINACAO_LINEAR        = 0
METODO_LSB_BIN                  = 1
METODO_LSB_RGB_GRAYSCALE        = 2
METODO_LSB_RGB_COLOR            = 3
METODO_WONG                     = 4
METODO_COX                      = 5
METODO_SHIFT_2_LSBITS           = 6

metodo_nomes = {
    METODO_COMBINACAO_LINEAR    : "Combinação Linear",
    METODO_LSB_BIN              : "LSB Bin",
    METODO_LSB_RGB_GRAYSCALE    : "LSB Rgb Grayscale",
    METODO_LSB_RGB_COLOR        : "LSB Rgb Color",
    METODO_WONG                 : "Wong",
    METODO_COX                  : "Cox",
    METODO_SHIFT_2_LSBITS       : "Shift 2-LSBits"
}




imagem_arq = ""
marca_arq = ""

imagem_pixbuf = None
marca_pixbuf = None
resp_pixbuf = None
fingerprint_pixbuf = None

imagem_ctrl = None

param_metodo = 0
param_alpha = 0.5
param_x = 0.7
param_y = 0.7
param_pixel_x = 0
param_pixel_y = 0





def metodo_configura( img_ctrl ):

    global imagem_ctrl
    imagem_ctrl = img_ctrl



def metodo_load_imagens( _imagem_arq, _marca_arq ):

    global imagem_ctrl
    global imagem_pixbuf, marca_pixbuf, imagem_arq, marca_arq

    if _imagem_arq == "" or _marca_arq == "":
        return

    if _imagem_arq != imagem_arq:

        imagem_arq = _imagem_arq
        imagem_pixbuf = gtk.gdk.pixbuf_new_from_file( imagem_arq )
        imagem_ctrl.set_from_pixbuf( imagem_pixbuf )

    if _marca_arq != marca_arq:

        marca_arq = _marca_arq
        marca_pixbuf = gtk.gdk.pixbuf_new_from_file( marca_arq )



def metodo_params( qual_metodo, alpha, x, y ):

    global param_metodo, param_alpha, param_x, param_y

    param_metodo = qual_metodo
    param_alpha = alpha
    param_x = x
    param_y = y



def metodo_run():
    global param_metodo

    if param_metodo == -1:
        param_metodo = METODO_COMBINACAO_LINEAR

    if param_metodo == METODO_COMBINACAO_LINEAR:
        metodo_run_combinacao_linear()

    elif param_metodo == METODO_LSB_BIN:
        metodo_run_lsb_bin()

    elif param_metodo == METODO_LSB_RGB_GRAYSCALE:
        metodo_run_lsb_rgb( color=False )

    elif param_metodo == METODO_LSB_RGB_COLOR:
        metodo_run_lsb_rgb( color=True )

    elif param_metodo == METODO_WONG:
        metodo_run_wong()

    elif param_metodo == METODO_COX:
        metodo_run_cox()

    elif param_metodo == METODO_SHIFT_2_LSBITS:
        metodo_run_2_lsbits()



def metodo_clip_ok():

    global param_x, param_y
    global param_pixel_x, param_pixel_y
    global imagem_pixbuf, marca_pixbuf

    w = imagem_pixbuf.get_width()
    h = imagem_pixbuf.get_height()

    param_pixel_x = int( param_x * w )
    param_pixel_y = int( param_y * h )

    marca_w = marca_pixbuf.get_width()
    marca_h = marca_pixbuf.get_height()

    if param_pixel_x + marca_w >= w:
        param_pixel_x = w - marca_w

    if param_pixel_y + marca_h >= h:
        param_pixel_y = h - marca_h

    if  marca_w < 0 or \
        marca_h < 0 or \
        param_pixel_x < 0 or \
        param_pixel_y < 0:
      return False

    return True


def metodo_run_combinacao_linear():

    global imagem_ctrl
    global param_alpha, param_x, param_y, imagem_pixbuf, marca_pixbuf

    alpha = param_alpha
    inv_alpha = 1.0 - alpha

    w = imagem_pixbuf.get_width()
    h = imagem_pixbuf.get_height()
    row = imagem_pixbuf.get_rowstride()

    mw = marca_pixbuf.get_width()
    mh = marca_pixbuf.get_height()
    mrow = marca_pixbuf.get_rowstride()

    if not metodo_clip_ok():
        return

    imagem_pixels = array( 'B', imagem_pixbuf.get_pixels() )
    marca_pixels = array( 'B', marca_pixbuf.get_pixels() )


    for y in range(mh):
        for x in range(mw):

            px = param_pixel_x + x
            py = param_pixel_y + y

            r1 = imagem_pixels[ (py * row) + (px * 3) + 0 ]
            g1 = imagem_pixels[ (py * row) + (px * 3) + 1 ]
            b1 = imagem_pixels[ (py * row) + (px * 3) + 2 ]

            r2 = marca_pixels[ (y * mrow) + (x * 3) + 0 ]
            g2 = marca_pixels[ (y * mrow) + (x * 3) + 1 ]
            b2 = marca_pixels[ (y * mrow) + (x * 3) + 2 ]

            r = int( r1 * alpha  +  r2 * inv_alpha )
            g = int( g1 * alpha  +  g2 * inv_alpha )
            b = int( b1 * alpha  +  b2 * inv_alpha )

            imagem_pixels[ (py * row) + (px * 3) + 0 ] = r
            imagem_pixels[ (py * row) + (px * 3) + 1 ] = g
            imagem_pixels[ (py * row) + (px * 3) + 2 ] = b

        if y % 3 == 0:
            progresso_run( (float(y) * mw + x) / (mw*mh) )


    resp_pixbuf = gtk.gdk.pixbuf_new_from_data( imagem_pixels.tostring(), \
        gtk.gdk.COLORSPACE_RGB, False, 8, w, h, row )

    imagem_ctrl.set_from_pixbuf( resp_pixbuf )



def metodo_run_lsb_bin():

    global imagem_ctrl
    global imagem_pixbuf, marca_pixbuf, param_x, param_y

    w = imagem_pixbuf.get_width()
    h = imagem_pixbuf.get_height()
    row = imagem_pixbuf.get_rowstride()

    mw = marca_pixbuf.get_width()
    mh = marca_pixbuf.get_height()
    mrow = marca_pixbuf.get_rowstride()

    if not metodo_clip_ok():
        return

    imagem_pixels = array( 'B', imagem_pixbuf.get_pixels() )
    marca_pixels = array( 'B', marca_pixbuf.get_pixels() )

    # zera todos os bits LSB
    for x in range(w):
        for y in range(h):
            pixel_b = imagem_pixels[ (y * row) + (x * 3) + 2 ]
            pixel_b = pixel_b & 0b11111110
            imagem_pixels[ (y * row) + (x * 3) + 2 ] = pixel_b


    # agora, grava na posicao (x, y) a marca d'água
    for y in range(mh):
        for x in range(mw):

            px = x + param_pixel_x
            py = y + param_pixel_y

            # pega o canal red da imagem e verifica se ele eh
            # maior ou igual a 127 pra tornar a imagem B&W
            marca_pixel_r = marca_pixels[ (y * mrow) + (x * 3) + 0 ]

            if marca_pixel_r > 127:
                imagem_pixel_b = imagem_pixels[ (py * row) + (px * 3) + 2 ]
                imagem_pixel_b = imagem_pixel_b | 0b00000001
                imagem_pixels[ (py * row) + (px * 3) + 2 ] = imagem_pixel_b

        if y % 3 == 0:
            progresso_run( (float(y) * mw + x) / (mw*mh) )


    resp_pixbuf = gtk.gdk.pixbuf_new_from_data( imagem_pixels.tostring(), \
        gtk.gdk.COLORSPACE_RGB, False, 8, w, h, row )

    imagem_ctrl.set_from_pixbuf( resp_pixbuf )


def metodo_run_lsb_rgb(color):

    global imagem_ctrl
    global imagem_pixbuf, marca_pixbuf, param_x, param_y

    w = imagem_pixbuf.get_width()
    h = imagem_pixbuf.get_height()
    row = imagem_pixbuf.get_rowstride()

    mw = marca_pixbuf.get_width()
    mh = marca_pixbuf.get_height()
    mrow = marca_pixbuf.get_rowstride()

    if not metodo_clip_ok():
        return

    imagem_pixels = array( 'B', imagem_pixbuf.get_pixels() )
    marca_pixels = array( 'B', marca_pixbuf.get_pixels() )

    # zera todos os bits LSB - dos 3 canais!!!
    for x in range(w):
        for y in range(h):
            pixel_r = imagem_pixels[ (y * row) + (x * 3) + 0 ]
            pixel_g = imagem_pixels[ (y * row) + (x * 3) + 1 ]
            pixel_b = imagem_pixels[ (y * row) + (x * 3) + 2 ]

            pixel_r = pixel_r & 0b11111110
            pixel_g = pixel_g & 0b11111110
            pixel_b = pixel_b & 0b11111110

            imagem_pixels[ (y * row) + (x * 3) + 0 ] = pixel_r
            imagem_pixels[ (y * row) + (x * 3) + 1 ] = pixel_g
            imagem_pixels[ (y * row) + (x * 3) + 2 ] = pixel_b


    # agora, grava na posicao (x, y) a marca d'água
    for y in range(mh):
        for x in range(mw):

            px = x + param_pixel_x
            py = y + param_pixel_y

            # podemos gravar 3 bits de um mesmo canal "grayscale" da
            # marca, nos 3 bits do pixel atual, ja que temos
            # (1 lsb R, 1 lsb G, 1 lsb B).

            marca_pixel_r = marca_pixels[ (y * mrow) + (x * 3) + 0 ]
            marca_pixel_g = marca_pixels[ (y * mrow) + (x * 3) + 1 ]
            marca_pixel_b = marca_pixels[ (y * mrow) + (x * 3) + 2 ]

            imagem_pixel_r = imagem_pixels[ (py * row) + (px * 3) + 0 ]
            imagem_pixel_g = imagem_pixels[ (py * row) + (px * 3) + 1 ]
            imagem_pixel_b = imagem_pixels[ (py * row) + (px * 3) + 2 ]

            if color:
                msb_r = marca_pixel_r & 0b10000000
                msb_g = marca_pixel_g & 0b10000000
                msb_b = marca_pixel_b & 0b10000000
            else:
                grayscale = ( marca_pixel_r + marca_pixel_g + marca_pixel_b ) / 3

                msb_r = (grayscale & 0b10000000) >> 7
                msb_g = (grayscale & 0b01000000) >> 6
                msb_b = (grayscale & 0b00100000) >> 5

            if msb_r != 0:
                imagem_pixel_r = imagem_pixel_r | 0b00000001
            if msb_g != 0:
                imagem_pixel_g = imagem_pixel_g | 0b00000001
            if msb_b != 0:
                imagem_pixel_b = imagem_pixel_b | 0b00000001

            imagem_pixels[ (py * row) + (px * 3) + 0 ] = imagem_pixel_r
            imagem_pixels[ (py * row) + (px * 3) + 1 ] = imagem_pixel_g
            imagem_pixels[ (py * row) + (px * 3) + 2 ] = imagem_pixel_b

        if y % 3 == 0:
            progresso_run( (float(y) * mw + x) / (mw*mh) )


    resp_pixbuf = gtk.gdk.pixbuf_new_from_data( imagem_pixels.tostring(), \
        gtk.gdk.COLORSPACE_RGB, False, 8, w, h, row )

    imagem_ctrl.set_from_pixbuf( resp_pixbuf )




def metodo_run_2_lsbits():
    global imagem_ctrl
    global imagem_pixbuf, marca_pixbuf, param_x, param_y

    w = imagem_pixbuf.get_width()
    h = imagem_pixbuf.get_height()
    row = imagem_pixbuf.get_rowstride()

    mw = marca_pixbuf.get_width()
    mh = marca_pixbuf.get_height()
    mrow = marca_pixbuf.get_rowstride()

    if not metodo_clip_ok():
        return

    imagem_pixels = array( 'B', imagem_pixbuf.get_pixels() )
    marca_pixels = array( 'B', marca_pixbuf.get_pixels() )

    # zera todos os 2 LSB
    for x in range(w):
        for y in range(h):
            img_pixel_r = imagem_pixels[ (y * row) + (x * 3) + 0 ]
            img_pixel_r = img_pixel_r & 0b11111100

            img_pixel_g = imagem_pixels[ (y * row) + (x * 3) + 1 ]
            img_pixel_g = img_pixel_g & 0b11111100

            img_pixel_b = imagem_pixels[ (y * row) + (x * 3) + 2 ]
            img_pixel_b = img_pixel_b & 0b11111100

            imagem_pixels[ (y * row) + (x * 3) + 0 ] = img_pixel_r
            imagem_pixels[ (y * row) + (x * 3) + 1 ] = img_pixel_g
            imagem_pixels[ (y * row) + (x * 3) + 2 ] = img_pixel_b


    # faz o shift dos 2 MSB
    for x in range(mw):
        for y in range(mh):
            mrk_pixel_r = marca_pixels[ (y * mrow) + (x * 3) + 0 ]
            mrk_pixel_r = mrk_pixel_r >> 6

            mrk_pixel_g = marca_pixels[ (y * mrow) + (x * 3) + 1 ]
            mrk_pixel_g = mrk_pixel_g >> 6

            mrk_pixel_b = marca_pixels[ (y * mrow) + (x * 3) + 2 ]
            mrk_pixel_b = mrk_pixel_b >> 6

            marca_pixels[ (y * mrow) + (x * 3) + 0 ] = mrk_pixel_r
            marca_pixels[ (y * mrow) + (x * 3) + 1 ] = mrk_pixel_g
            marca_pixels[ (y * mrow) + (x * 3) + 2 ] = mrk_pixel_b


    # agora, grava na posicao (x, y) a marca d'água
    for y in range(mh):
        for x in range(mw):
            px = x + param_pixel_x
            py = y + param_pixel_y

            mrk_pixel_r = marca_pixels[ (y * mrow) + (x * 3) + 0 ]
            mrk_pixel_g = marca_pixels[ (y * mrow) + (x * 3) + 1 ]
            mrk_pixel_b = marca_pixels[ (y * mrow) + (x * 3) + 2 ]

            img_pixel_r = imagem_pixels[ (py * row) + (px * 3) + 0 ]
            img_pixel_g = imagem_pixels[ (py * row) + (px * 3) + 1 ]
            img_pixel_b = imagem_pixels[ (py * row) + (px * 3) + 2 ]

            #insere os bits da marca na imagem
            img_pixel_r = img_pixel_r | mrk_pixel_r
            img_pixel_g = img_pixel_g | mrk_pixel_g
            img_pixel_b = img_pixel_b | mrk_pixel_b

            imagem_pixels[ (py * row) + (px * 3) + 0 ] = img_pixel_r
            imagem_pixels[ (py * row) + (px * 3) + 1 ] = img_pixel_g
            imagem_pixels[ (py * row) + (px * 3) + 2 ] = img_pixel_b

        if y % 3 == 0:
            progresso_run( (float(y) * mw + x) / (mw*mh) )


    resp_pixbuf = gtk.gdk.pixbuf_new_from_data( imagem_pixels.tostring(), \
        gtk.gdk.COLORSPACE_RGB, False, 8, w, h, row )

    imagem_ctrl.set_from_pixbuf( resp_pixbuf )


def fingerprint ( data ):
	if data > 127:
		return 255
	return 0

def wm_encode ( mark, mw, mh, row ):
	for y in range ( mh / 2 ):
		for x in range ( mw ):
			pixel_front = mark[ (y * row) + (x * 3) + 0 ]
			pixel_back = mark[ ((mh - y - 1) * row) + ( mw - x - 1 )*3 + 0 ]
			aux = pixel_front
			pixel_front = pixel_back
			pixel_back = aux
			mark[ (y * row) + (x * 3) + 0 ] = pixel_front
			mark[ ((mh - y - 1) * row) + ( mw - x - 1 )*3 + 0 ] = pixel_back

	return mark

def wm_decode ( mark, mw, mh, row ):
	for y in range ( mh / 2 ):
		for x in range ( mw ):
			pixel_front = mark[ (y * row) + (x * 3) + 0 ]
			pixel_back = mark[ ((mh - y - 1) * row) + ( mw - x - 1 )*3 + 0 ]
			aux = pixel_front
			pixel_front = pixel_back
			pixel_back = aux
			mark[ (y * row) + (x * 3) + 0 ] = pixel_front
			mark[ ((mh - y - 1) * row) + ( mw - x - 1 )*3 + 0 ] = pixel_back

			pixel_front = mark[ (y * row) + (x * 3) + 1 ]
			pixel_back = mark[ ((mh - y - 1) * row) + ( mw - x - 1 )*3 + 1 ]
			aux = pixel_front
			pixel_front = pixel_back
			pixel_back = aux
			mark[ (y * row) + (x * 3) + 1 ] = pixel_front
			mark[ ((mh - y - 1) * row) + ( mw - x - 1 )*3 + 1 ] = pixel_back

			pixel_front = mark[ (y * row) + (x * 3) + 2 ]
			pixel_back = mark[ ((mh - y - 1) * row) + ( mw - x - 1 )*3 + 2 ]
			aux = pixel_front
			pixel_front = pixel_back
			pixel_back = aux
			mark[ (y * row) + (x * 3) + 2 ] = pixel_front
			mark[ ((mh - y - 1) * row) + ( mw - x - 1 )*3 + 2 ] = pixel_back

	return mark


def metodo_run_wong():
    global imagem_ctrl
    global imagem_pixbuf, marca_pixbuf, fingerprint_pixbuf, param_x, param_y

    w = imagem_pixbuf.get_width()
    h = imagem_pixbuf.get_height()
    row = imagem_pixbuf.get_rowstride()

    mw = marca_pixbuf.get_width()
    mh = marca_pixbuf.get_height()
    mrow = marca_pixbuf.get_rowstride()

    if not metodo_clip_ok():
        return

    imagem_pixels = array( 'B', imagem_pixbuf.get_pixels() )
    fingerprint_pixels = array( 'B', imagem_pixbuf.get_pixels() )
    marca_pixels = array( 'B', marca_pixbuf.get_pixels() )
	#zera todos os LSB da imagem a ser marcada
    for x in range(w):
        for y in range(h):
            pixel_b = imagem_pixels[ (y * row) + (x * 3) + 2 ]
            pixel_b = pixel_b & 0b11111110
            imagem_pixels[ (y * row) + (x * 3) + 2 ] = pixel_b

            pixel_fp = fingerprint_pixels[ (y * row) + (x * 3) + 2 ]
            pixel_fp = pixel_fp & 0b11111110
		    #calcula a impressao digital do canal azul da imagem
            pixel_fp = fingerprint( pixel_fp )
            fingerprint_pixels[ (y * row) + (x * 3) + 2 ] = pixel_fp

	#calcula o ou exclusivo da impressao digital com a marca dagua
    for y in range(mh):
        for x in range(mw):

            px = x + param_pixel_x
            py = y + param_pixel_y

            marca_pixel = marca_pixels[ (y * mrow) + (x * 3) + 0 ]
            marca_pixel = fingerprint ( marca_pixel )
            pixel_fp = fingerprint_pixels[ (py * row) + (x * 3) + 2 ]
            marca_pixel ^= pixel_fp
            marca_pixels[ (y * mrow) + (x * 3) + 0 ] = marca_pixel

    #criptografa a marca d'agua
    marca_pixels = wm_encode ( marca_pixels, mw, mh, mrow )

    #insere a marca na imagem
    for y in range(mh):
        for x in range(mw):

            px = x + param_pixel_x
            py = y + param_pixel_y

            marca_pixel = marca_pixels[ (y * mrow) + (x * 3) + 0 ]
            imagem_pixel_b = imagem_pixels[ (py * row) + (px * 3) + 2 ]
            marca_pixel = marca_pixel & 0b00000001
            imagem_pixel_b = imagem_pixel_b | marca_pixel
            imagem_pixels[ (py * row) + (px * 3) + 2 ] = imagem_pixel_b

        if y % 3 == 0:
            progresso_run( (float(y) * mw + x) / (mw*mh) )


    resp_pixbuf = gtk.gdk.pixbuf_new_from_data( imagem_pixels.tostring(), \
        gtk.gdk.COLORSPACE_RGB, False, 8, w, h, row )

    fingerprint_pixbuf = gtk.gdk.pixbuf_new_from_data( fingerprint_pixels.tostring(), \
        gtk.gdk.COLORSPACE_RGB, False, 8, w, h, row )

    imagem_ctrl.set_from_pixbuf( resp_pixbuf )


def metodo_run_cox():
    print( "O método está sendo implementado" )



def metodo_extract(tipo):
    if not( tipo == METODO_LSB_BIN or \
            tipo == METODO_LSB_RGB_GRAYSCALE or \
            tipo == METODO_LSB_RGB_COLOR or \
            tipo == METODO_WONG or \
            tipo == METODO_SHIFT_2_LSBITS ):
        return

    global imagem_ctrl, marca_pixbuf

    resp = imagem_ctrl.get_pixbuf()
    if resp == None:
        return

    w = resp.get_width()
    h = resp.get_height()
    row = resp.get_rowstride()

    pixels = array( 'B', resp.get_pixels() )

    # zera todos os bits que não são o LSB
    for x in range(w):
        for y in range(h):
            pixel_r = pixels[ (y * row) + (x * 3) + 0 ]
            pixel_g = pixels[ (y * row) + (x * 3) + 1 ]
            pixel_b = pixels[ (y * row) + (x * 3) + 2 ]

            if tipo == METODO_LSB_BIN or tipo == METODO_WONG:
                pixel_b = pixel_b & 0b00000001

                if pixel_b != 0:
                    pixel_b = 255

                pixel_r = pixel_g = pixel_b

            elif tipo == METODO_LSB_RGB_GRAYSCALE:
                pixel_r = pixel_r & 0b00000001
                pixel_g = pixel_g & 0b00000001
                pixel_b = pixel_b & 0b00000001

                msb_1 = 0b11111111 & (pixel_r << 7)
                msb_2 = 0b11111111 & (pixel_g << 6)
                msb_3 = 0b11111111 & (pixel_b << 5)

                grayscale = msb_1 | msb_2 | msb_3

                pixel_r = pixel_g = pixel_b = grayscale

            elif tipo == METODO_LSB_RGB_COLOR:
                pixel_r = (pixel_r & 0b00000001) << 7
                pixel_g = (pixel_g & 0b00000001) << 7
                pixel_b = (pixel_b & 0b00000001) << 7

            elif tipo == METODO_SHIFT_2_LSBITS:
                pixel_r = 0b11111111 & (pixel_r << 6)
                pixel_g = 0b11111111 & (pixel_g << 6)
                pixel_b = 0b11111111 & (pixel_b << 6)


            pixels[ (y * row) + (x * 3) + 0 ] = pixel_r
            pixels[ (y * row) + (x * 3) + 1 ] = pixel_g
            pixels[ (y * row) + (x * 3) + 2 ] = pixel_b

        if y % 3 == 0:
            progresso_run( (float(y) * w + x) / (w*h) )


    if tipo == METODO_WONG:
        #decodifica a marca d'agua de Wong extraida'

        pixels = wm_decode(pixels, w, h, row)

        mw = marca_pixbuf.get_width()
        mh = marca_pixbuf.get_height()
        mrow = marca_pixbuf.get_rowstride()

        fingerprint_pixels = array( 'B', fingerprint_pixbuf.get_pixels() )

        #faz o ou exclusivo da marca extraida com a marca original
        for y in range(mh):
            for x in range(mw):
                px = x + param_pixel_x
                py = y + param_pixel_y

                pixel_r = pixels[ (y * row) + (x * 3) + 0 ]
                pixel_g = pixels[ (y * row) + (x * 3) + 1 ]
                pixel_b = pixels[ (y * row) + (x * 3) + 2 ]
                pixel_fp = fingerprint_pixels[ (y * mrow) + (x * 3) + 2 ]
                pixel_r ^= pixel_fp
                pixel_g ^= pixel_fp
                pixel_b ^= pixel_fp
                pixels[ (y * row) + (x * 3) + 0 ] = pixel_r
                pixels[ (y * row) + (x * 3) + 1 ] = pixel_g
                pixels[ (y * row) + (x * 3) + 2 ] = pixel_b



    resp_pixbuf = gtk.gdk.pixbuf_new_from_data( pixels.tostring(), \
        gtk.gdk.COLORSPACE_RGB, False, 8, w, h, row )

    imagem_ctrl.set_from_pixbuf( resp_pixbuf )



def metodo_inverte():

    global imagem_ctrl

    resp = imagem_ctrl.get_pixbuf()
    if resp == None:
        return

    w = resp.get_width()
    h = resp.get_height()
    row = resp.get_rowstride()

    pixels = array( 'B', resp.get_pixels() )

    for x in range(w):
        for y in range(h):
            pixel_r = pixels[ (y * row) + (x * 3) + 0 ]
            pixel_g = pixels[ (y * row) + (x * 3) + 1 ]
            pixel_b = pixels[ (y * row) + (x * 3) + 2 ]

            pixel_r = 255 - pixel_r
            pixel_g = 255 - pixel_g
            pixel_b = 255 - pixel_b

            pixels[ (y * row) + (x * 3) + 0 ] = pixel_r
            pixels[ (y * row) + (x * 3) + 1 ] = pixel_g
            pixels[ (y * row) + (x * 3) + 2 ] = pixel_b

        if y % 3 == 0:
            progresso_run( (float(y) * w + x) / (w*h) )


    resp_pixbuf = gtk.gdk.pixbuf_new_from_data( pixels.tostring(), \
        gtk.gdk.COLORSPACE_RGB, False, 8, w, h, row )

    imagem_ctrl.set_from_pixbuf( resp_pixbuf )


def metodo_espelha(v):

    global imagem_ctrl

    resp = imagem_ctrl.get_pixbuf()
    if resp == None:
        return

    w = resp.get_width()
    h = resp.get_height()
    row = resp.get_rowstride()

    pixels = array( 'B', resp.get_pixels() )
    esp_pixels = pixels.__copy__()

    for x in range(w):
        for y in range(h):
            pixel_r = pixels[ (y * row) + (x * 3) + 0 ]
            pixel_g = pixels[ (y * row) + (x * 3) + 1 ]
            pixel_b = pixels[ (y * row) + (x * 3) + 2 ]

            tx = x
            ty = y

            if v:
                ty = h-1 - y
            else:
                tx = w-1 - x

            esp_pixels[ (ty * row) + (tx * 3) + 0 ] = pixel_r
            esp_pixels[ (ty * row) + (tx * 3) + 1 ] = pixel_g
            esp_pixels[ (ty * row) + (tx * 3) + 2 ] = pixel_b

        if y % 3 == 0:
            progresso_run( (float(y) * w + x) / (w*h) )


    resp_pixbuf = gtk.gdk.pixbuf_new_from_data( esp_pixels.tostring(), \
        gtk.gdk.COLORSPACE_RGB, False, 8, w, h, row )

    imagem_ctrl.set_from_pixbuf( resp_pixbuf )
